﻿//#define _CRT_SECURE_NO_WARNINGS 1
//
//#include<iostream>
//using namespace std;


//构造函数，名字与类名字一样
//这里类Date，构造函数Date名字相同
//class Date
//{
//public:
//	//⽆参构造函数 
//	Date()//#1
//	{
//		_year = 1;
//		_month = 1;
//		_day = 1;
//	}
//	//带参构造函数 
//	Date(int year)//#2
//	{
//		_year = year;
//	}
//	Date(int year, int month, int day)//#3
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void Print()
//	{
//		cout << _year << "/" << _month << "/" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	Date d1; //这里定义类d1，没有输入参数，那么默认调用无参函数Data
//	Date d2(2025); //这里输入参数，对应#2，year赋值为2025，month和day未初始化，随机值
//	Date d3(2025, 1, 1); //对应#3
//
//
//	d1.Print();
//	d2.Print();
//	d3.Print();
//
//	return 0;
//}
//如果类中没有显式定义构造函数，则C++编译器会⾃动⽣成⼀个⽆参的默认构造函数
//⼀旦⽤户显式定义编译器将不再⽣成



//析构函数
//typedef int STDataType;
//class Stack
//{
//public:
//	Stack(int n = 4)
//	{
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//	~Stack()//析构函数与构造函数类似，名字与类相同，不过前面加个~号
//	{
//		cout << "~Stack()" << endl;
//		free(_a);
//		_a = nullptr;
//		_top = _capacity = 0;
//	}
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//对象⽣命周期结束时，系统会⾃动调⽤析构函数，功能与STDestory()类似
//而构造函数功能与STInit()类似



//拷贝构造函数
//浅拷贝逐成员复制，深拷贝还复制子对象。区别不在于结果(地址是否相同),浅拷贝后地址也可能不同(比如int a基本类型成员的复制)。
//浅拷贝不用另外用malloc等函数开辟空间，直接定义复制;而深拷贝需要用malloc等函数开辟空间。然后定义要拷贝对象数据类型，再把数据拷贝过来。
//深拷贝:类似复制，有不同
//浅拷贝:类似引用，有不同
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	Date(const Date& d)//定义拷贝构造函数(浅拷贝)
//	{
//		_year = d._year;
//		_month = d._month;
//		_day = d._day;
//	}
//	void Print()
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	Date d1;
//
//	Date d2 = d1;//浅拷贝
//	Date d3(d1);//浅拷贝
//
//	return 0;
//}
//如果不定义拷贝构造函数，直接拷贝的话，系统会使用默认的拷贝构造函数
//所以不是深拷贝，想要深拷贝只能自己根据自己定义的变量去实现深拷贝构造函数

//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	//编译报错：error C2652: “Date”: ⾮法的复制构造函数: 第⼀个参数不应是“Date” 
//	//Date(Date d)
//	//假如这样构造成功的话
//	//那么对于Data d2(d1),d1传参到拷贝构造函数,Data d1又会传参给拷贝构造函数，然后无限递归
//	Date(const Date& d)
//	{//常引用本质传的是地址
//		//想想以前学的，传参的过程实际是一个复制的过程，如果传入的是数据本身，那么就会开辟一片空间，
//		//把要传的数据复制一份到这片空间，然后函数对这片空间进行操作，会生成一个中间值。
//		//如果传的是数据上的地址，那么函数就会直接调用这块地址下的数据，不会生成中间值。
//	//那么回过头来看这个常引用就类似传入地址
//	//而Data(Data d)，d1传入的是数据本身，系统要先开辟空间，复制一份d1，再传给Data(Data d)，
//	//因为我们定义了拷贝构造函数，所以就会调用拷贝构造函数Data(Data d)，然后无线递归循环
//		_year = d._year;
//		_month = d._month;
//		_day = d._day;
//	}
//	Date(Date * d)
//	{
//		_year = d->_year;
//		_month = d->_month;
//		_day = d->_day;
//	}
//	void Print()
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//void Func1(Date d)
//{
//	cout << &d << endl;
//	d.Print();
//}
//Date& Func2()
//{
//	Date tmp(2024, 7, 5);
//	tmp.Print();
//	return tmp;
//}
//int main()
//{
//	Date d1(2024, 7, 5);
//
//	Func1(d1);//调用Func(d1)时传值传参会先调用拷贝构造函数，再传值传参给Func1
//	//调试时看一下先进入哪个函数（先进拷贝构造函数，再进Func1）
//	cout << &d1 << endl;
//
//	//Date d2(&d1);
//	//d1.Print();
//	//d2.Print();
//
//	//Date d3(d1);
//	//d2.Print();
//
//	//Date d4 = d1;
//	//d2.Print();
//
//	//Date ret = Func2();
//	//ret.Print();
//
//	return 0;
//}




//赋值运算符重载
//简单事例，后续更详细
//class Data
//{
//public:
//	Data(int a = 1, int b = 1)
//	{
//		_a = a;
//		_b = b;
//	}
//	void Print() 
//	{
//		cout << _a << _b << endl;
//	}
//
//int _a;
//int _b;
//};
//bool operator==(const Data& d1, const Data& d2)
//{
//	return d1._a == d2._a
//		&& d2._b == d2._b;
//}
//int operator+(const Data& d1, const Data& d2)
//{
//	return d1._a * d1._b + d2._a * d2._b;
//}
//int main()
//{
//	Data d1(3, 4);
//	Data d2(1, 2);
//
//	cout << operator==(d1, d2) << endl;//0
//
//	cout << d1 + d2 << endl;//3*4+1*2
//
//	return 0;
//}















